package net.oktaeder.office.view;

import java.util.ArrayList;
import java.util.Iterator;

import net.oktaeder.office.ConfigurationHelper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * This class acts as a mail storage and a gateway between client program and
 * actual application
 * 
 * @author tuukka
 *
 */
public class MailDaemon {
	
	private static Log log = LogFactory.getLog(MailDaemon.class);
	private static MailDaemon instance;
	
	private ArrayList<Mail> mails;
	private IMailer mailer;
	
	
	private MailDaemon() throws Exception {
		try {
			String mailerClass;
			log.info("MailDaemon starting up");
			mailerClass = ConfigurationHelper.getConfiguration().getString("system.mailer[@class]");
			mails = new ArrayList<Mail>();
			Class classDefinition = Class.forName(mailerClass);
			mailer = (IMailer)classDefinition.newInstance();			
		} catch (Exception ex) {
			log.fatal("Failed to get instance of MailDaemon", ex);
			throw new Exception("Failed to get instance of MailDaemon", ex);
		}

	}
	
	public static synchronized MailDaemon getInstance() throws Exception {
		try {
			if (instance==null) {
				instance = new MailDaemon();
			}
			return instance;	
		} catch (Exception ex) {
			log.fatal("Failed to get instance of MailDaemon", ex);
			throw new Exception("Failed to get instance of MailDaemon", ex);
		}
	}
	
	public void addMail(Mail mail) {
		mails.add(mail);
	}
	
	public void removeMail(Mail mail) {
		mails.remove(mail);
	}
	
	public int getMailCount() {
		return mails.size();
	}
	
	public Iterator<Mail> iterator() {
		return mails.iterator();
	}
	
	/**
	 * Checks external system for new mails and updates the internal
	 * mail queue accordingly. Also purges the queue from mails marked for
	 * deletion.
	 */
	public void update() throws Exception {
		ArrayList<Mail> deletedMails;
		Iterator<Mail> iterator;
		Mail mail;
		
		try {
			deletedMails = new ArrayList<Mail>();
			iterator = mails.iterator();
			
			while (iterator.hasNext()) {
				mail = iterator.next();
				if (mail.getDeletion() == true) {
					deletedMails.add(mail);
				}
			}
			
			mails.removeAll(deletedMails);		
			mailer.updateMailQueue();			
		} catch (Exception ex) {
			log.error("Mail queue update failed", ex);
			throw new Exception("Mail queue update failed", ex);
		}

	}
}